package org.ysling.litemall.wx.web;
// Copyright (c) [ysling] [927069313@qq.com]
// [litemall-plus] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//             http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.ysling.litemall.core.service.QCodeService;
import org.ysling.litemall.core.utils.JacksonUtil;
import org.ysling.litemall.core.utils.response.ResponseUtil;
import org.ysling.litemall.core.validator.Order;
import org.ysling.litemall.core.validator.Sort;
import org.ysling.litemall.db.domain.LitemallGoods;
import org.ysling.litemall.db.domain.LitemallRewardTask;
import org.ysling.litemall.db.domain.LitemallReward;
import org.ysling.litemall.db.service.LitemallGoodsService;
import org.ysling.litemall.db.service.LitemallRewardTaskService;
import org.ysling.litemall.db.service.LitemallRewardService;
import org.ysling.litemall.db.service.LitemallUserService;
import org.ysling.litemall.db.vomain.UserVo;
import org.ysling.litemall.wx.annotation.LoginUser;
import org.ysling.litemall.wx.service.WxRewardService;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/wx/reward")
@Validated
public class WxRewardController {

    @Autowired
    private LitemallGoodsService goodsService;
    @Autowired
    private LitemallRewardTaskService rewardTaskService;
    @Autowired
    private LitemallRewardService rewardService;
    @Autowired
    private LitemallUserService userService;
    @Autowired
    private WxRewardService wxRewardService;
    @Resource
    private QCodeService qCodeService;

    @GetMapping("/list")
    public Object rewardTaskList(String goodsId, @LoginUser Integer userId,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit,
                       @Sort @RequestParam(defaultValue = "add_time") String sort,
                       @Order @RequestParam(defaultValue = "desc") String order) {

        ArrayList<Map> rewardMaps = new ArrayList<>();
        //获取所有赏金规则
        List<LitemallRewardTask> rewardTasks = rewardTaskService.querySelective(goodsId, page, limit, sort, order);
        for (LitemallRewardTask rewardTask :rewardTasks) {
            HashMap<String, Object> rewardMap = new HashMap<>();
            rewardMap.put("rewardTask" , rewardTask);
            Integer countReward = rewardService.countReward(rewardTask.getId());
            rewardMap.put("percentage" , percentage(countReward.longValue(),rewardTask.getRewardMember()));

            if (userId != null){
                //获取分享记录
                LitemallReward sharer = rewardService.findSharer(userId, rewardTask.getId());
                if (sharer != null){
                    List<LitemallReward> rewards = rewardService.queryJoinRecord(sharer.getId());
                    PageInfo<LitemallReward> rewardPageInfo = PageInfo.of(rewards);
                    //获取用户信息
                    ArrayList<UserVo> joiners = new ArrayList<>();
                    for (LitemallReward reward :rewards) {
                        joiners.add(userService.findUserVoById(reward.getUserId()));
                    }
                    rewardMap.put("total" , rewardPageInfo.getTotal());
                    rewardMap.put("joiners" , joiners);
                }
            }
            rewardMaps.add(rewardMap);
        }
        return ResponseUtil.okList(rewardMaps ,rewardTasks);
    }

    /**
     * 获取两数百分比
     * @param divisor 除数
     * @param dividend 被除数
     * @return
     */
    private String percentage(Long divisor, Integer dividend){
        BigDecimal divideNum = BigDecimal.valueOf(divisor).divide(
                BigDecimal.valueOf(dividend), 2, RoundingMode.CEILING);
        //将结果百分比
        NumberFormat percent = NumberFormat.getPercentInstance();
        percent.setMaximumFractionDigits(2);
        return percent.format(divideNum.doubleValue());
    }

    /**
     * 参加赏金
     * @param rewardId  活动ID
     * @return
     */
    @GetMapping("/join")
    public Object join(@NotNull Integer rewardId) {
        LitemallReward reward = rewardService.findById(rewardId);
        if (reward == null) {
            return ResponseUtil.badArgumentValue();
        }

        LitemallRewardTask rewardTask = rewardTaskService.findById(reward.getTaskId());
        if (rewardTask == null) {
            return ResponseUtil.badArgumentValue();
        }

        if (rewardService.countReward(rewardTask.getId()) >= rewardTask.getRewardMember()){
            return ResponseUtil.fail(800,"活动已结束");
        }

        LitemallGoods goods = goodsService.findById(rewardTask.getGoodsId());
        if (goods == null) {
            return ResponseUtil.badArgumentValue();
        }

        Map<String, Object> result = new HashMap<>();
        result.put("reward", reward);
        result.put("goodId", goods.getId());
        return ResponseUtil.ok(result);
    }

    @PostMapping("/create")
    public Object create(@LoginUser Integer userId, @RequestBody String body) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }

        Integer rewardTaskId = JacksonUtil.parseInteger(body, "rewardTaskId");
        Object serviceReward = wxRewardService.isReward(rewardTaskId);
        if (serviceReward != null){
            return serviceReward;
        }

        LitemallReward reward = rewardService.findSharer(userId, rewardTaskId);
        if (reward != null) {
            return ResponseUtil.ok(reward);
        }

        reward = new LitemallReward();
        reward.setUserId(userId);
        reward.setTaskId(rewardTaskId);
        reward.setAward(BigDecimal.valueOf(0));

        rewardService.add(reward);
        return ResponseUtil.ok(reward);
    }

}
